// ------------------------------------------------------------
// JAL and JALR test program
//
// Tests:
// 1. JAL function call and return address
// 2. JAL forward unconditional jump
// 3. JAL backward unconditional jump
// 4. JAL with rd=x0 does not change x0
//
// Expected:
// x1 = 8       return byte address
// x5 = 15      function result
// x6 = 25      forward jump result
// x8 = 3       backward jump count
// x0 = 0
// ------------------------------------------------------------

start:

// ------------------------------------------------------------
// Test 1: Call a function.
//
// This ADDI is at byte address 0.
// JAL is at byte address 4.
// Therefore, x1 should receive address 8.
// ------------------------------------------------------------

addi x5, x0, 10

jal  x1, AddFive

AfterFunction:

cout << "Function result x5 = " << x5 << endl;
cout << "Return address x1 = " << x1 << endl;

// ------------------------------------------------------------
// Test 2: Forward unconditional jump.
//
// The instruction that loads -1 must be skipped.
// ------------------------------------------------------------

addi x6, x0, 0

jal  x0, SkipBadCode

// This instruction must not execute.

addi x6, x0, -1

SkipBadCode:

addi x6, x0, 25

cout << "Forward jump result x6 = " << x6 << endl;

// ------------------------------------------------------------
// Test 3: Backward JAL.
//
// x7 is the loop counter.
// x8 counts how many times LoopBody executes.
// ------------------------------------------------------------

addi x7, x0, 3
addi x8, x0, 0

// Jump forward to the loop test.

jal  x0, LoopCheck

LoopBody:

addi x8, x8, 1
addi x7, x7, -1

LoopCheck:

// Continue when x7 is not zero.

bne  x7, x0, JumpBackward

// Loop is complete.

jal  x0, TestComplete

JumpBackward:

// This JAL must resolve to a negative offset.

jal  x0, LoopBody

TestComplete:

cout << "Backward jump count x8 = " << x8 << endl;
cout << "Register x0 = " << x0 << endl;

jal  x0, ProgramDone

// ------------------------------------------------------------
// Function: AddFive
//
// Adds 5 to x5 and returns through x1.
// ------------------------------------------------------------

AddFive:

addi x5, x5, 5

// Return to the byte address stored in x1.

jalr x0, 0(x1)

// ------------------------------------------------------------
// Stop here.
// ------------------------------------------------------------

ProgramDone:


